package cn.tom.tompicturebackend.service.impl;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.tom.tompicturebackend.exception.BusinessException;
import cn.tom.tompicturebackend.exception.ErrorCode;
import cn.tom.tompicturebackend.exception.ThrowUtils;
import cn.tom.tompicturebackend.mapper.SpaceMapper;
import cn.tom.tompicturebackend.mapper.UserMapper;
import cn.tom.tompicturebackend.model.dto.space.SpaceAddRequest;
import cn.tom.tompicturebackend.model.dto.space.SpaceQueryRequest;
import cn.tom.tompicturebackend.model.entity.Space;
import cn.tom.tompicturebackend.model.entity.User;
import cn.tom.tompicturebackend.model.enums.SpaceLevelEnum;
import cn.tom.tompicturebackend.model.enums.SpaceTypeEnum;
import cn.tom.tompicturebackend.model.vo.SpaceVO;
import cn.tom.tompicturebackend.service.SpaceService;
import cn.tom.tompicturebackend.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.swing.text.html.Option;
import java.util.Date;
import java.util.Optional;

@Service
@Slf4j
public class SpaceServiceImpl extends ServiceImpl<SpaceMapper, Space>
        implements SpaceService {

    @Resource
    private TransactionTemplate transactionTemplate;

    @Resource
    private UserService userService;

    @Override
    public long addSpace(SpaceAddRequest spaceAddRequest, User loginUser) {

        //默认值
        if(StrUtil.isBlank(spaceAddRequest.getSpaceName())){
            spaceAddRequest.setSpaceName("默认空间");
        }
        if(spaceAddRequest.getSpaceLevel() == null){
            spaceAddRequest.setSpaceLevel(SpaceLevelEnum.COMMON.getValue());
        }
        if(spaceAddRequest.getSpaceType() == null){
            spaceAddRequest.setSpaceType(SpaceTypeEnum.PRIVATE.getValue());
        }

        Space space = new Space();

        BeanUtils.copyProperties(spaceAddRequest, space);
        //填充数据
        this.fillSpaceBySpaceLevel(space);
        //数据校验
        this.validSpace(space, true);
        Long id = loginUser.getId();
        space.setUserId(id);

        //权限检验
        if(SpaceLevelEnum.COMMON.getValue() != spaceAddRequest.getSpaceLevel() && !userService.isAdmin(loginUser)){

        }
        //针对用户进行加锁
        String lock = String.valueOf(id).intern();
        synchronized (lock){
            Long newSpaceId = transactionTemplate.execute(
                    status -> {
                        boolean exists = this.lambdaQuery()
                                .eq(Space::getUserId,id)
                                .eq(Space::getSpaceType,spaceAddRequest.getSpaceType())
                                .exists();
                        ThrowUtils.throwIf(exists, ErrorCode.OPERATION_ERROR,"每个用户仅能有一个私有空间");
                        //写入数据库
                        boolean result = this.save(space);
                        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
                        return space.getId();
                    }
            );
            return Optional.ofNullable(newSpaceId).orElse(-1L);
        }

    }

    @Override
    public void validSpace(Space space, boolean add) {

        ThrowUtils.throwIf(space == null, ErrorCode.PARAMS_ERROR);
        //从对象中取值

        String spaceName = space.getSpaceName();
        Integer spaceLevel = space.getSpaceLevel();
        Integer spaceType = space.getSpaceType();
        SpaceTypeEnum spaceTypeEnum = SpaceTypeEnum.getEnumByValue(spaceType);

        SpaceLevelEnum spaceLevelEnum = SpaceLevelEnum.getEnumByValue(spaceLevel);
        //要创建

        if(add){
            if(StrUtil.isBlank(spaceName)){
                throw new BusinessException(ErrorCode.SYSTEM_ERROR,"空间名称不能为空");

            }
            if(spaceType == null){
                throw new BusinessException(ErrorCode.SYSTEM_ERROR,"空间类型不能为空");
            }
            if(spaceLevel == null){
                throw new BusinessException(ErrorCode.SYSTEM_ERROR,"空间等级不能为空");
        }
        //修改数据时，如果要改空间级别
            if(spaceLevel !=null && spaceLevelEnum ==null){
                throw new BusinessException(ErrorCode.SYSTEM_ERROR,"空间等级不存在");
            }
            if(StrUtil.isNotBlank(spaceName) && spaceName.length() > 30){
                throw new BusinessException(ErrorCode.SYSTEM_ERROR,"空间名称不能超过30个字符");
            }
            if(spaceType !=null && spaceTypeEnum ==null){
                throw new BusinessException(ErrorCode.SYSTEM_ERROR,"空间类型不存在");
            }

    }}

    @Override
    public SpaceVO getSpaceVO(Space space, HttpServletRequest request) {
        return null;
    }

    @Override
    public Page<SpaceVO> getSpaceVOPage(Page<Space> spacePage, HttpServletRequest request) {
        return null;
    }

    @Override
    public QueryWrapper<Space> getQueryWrapper(SpaceQueryRequest spaceQueryRequest) {
        Long id = spaceQueryRequest.getId();
        Long userId = spaceQueryRequest.getUserId();
        String spaceName = spaceQueryRequest.getSpaceName();
        Integer spaceLevel = spaceQueryRequest.getSpaceLevel();
        Integer spaceType = spaceQueryRequest.getSpaceType();
        int current = spaceQueryRequest.getCurrent();
        int pageSize = spaceQueryRequest.getPageSize();
        String sortField = spaceQueryRequest.getSortField();
        String sortOrder = spaceQueryRequest.getSortOrder();

        QueryWrapper<Space> spaceQueryWrapper = new QueryWrapper<>();
        spaceQueryWrapper.eq(ObjUtil.isNotEmpty(spaceType),"spaceType",spaceType);
        return null;
    }

    @Override
    public void fillSpaceBySpaceLevel(Space space) {
        //根据空间级别，自动填充限额
        SpaceLevelEnum spaceLevelEnum = SpaceLevelEnum.getEnumByValue(space.getSpaceLevel());
        if(spaceLevelEnum ==null){
            long maxSize = spaceLevelEnum.getMaxSize();
            if(space.getMaxSize() ==null){
                space.setMaxSize(maxSize);
            }
            long maxCount = spaceLevelEnum.getMaxCount();
            if(space.getMaxCount() ==null){
                space.setMaxCount(maxCount);
            }
        }

    }

    @Override
    public void checkSpaceAuth(User loginUser, Space space) {

    }
}
